package com.buanalintas.sandals.pos.saleshop;

import com.buanalintas.bynga.Action;
import com.buanalintas.bynga.Controller;
import com.buanalintas.bynga.Dictionary;
import com.buanalintas.bynga.Field;
import com.buanalintas.bynga.Logger;
import com.buanalintas.bynga.Page;
import com.buanalintas.bynga.Persistence;
import com.buanalintas.bynga.Sequence;
import com.buanalintas.bynga.Utility;
import com.buanalintas.bynga.formatter.DateFormatter;
import com.buanalintas.bynga.formatter.MoneyFormatter;
import com.buanalintas.sandals.pos.entities.PosMasterItemStock;
import com.buanalintas.sandals.pos.entities.PosMasterStatus;
import com.buanalintas.sandals.pos.entities.PosTransactionItemStock;
import com.buanalintas.sandals.pos.entities.PosTransactionSaleDetail;
import com.buanalintas.sandals.pos.entities.PosTransactionSaleShop;
import com.buanalintas.sandals.pos.entities.PosTransactionSaleShopDetail;
import com.buanalintas.sandals.pos.item.Item;
import com.buanalintas.sandals.pos.saleshopdetail.SaleShopDetail;
import com.buanalintas.sandals.pos.status.Status;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.List;
import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class SaleShop extends Page {

    private Field saleShopId;
    private Field saleShopUnitId;
    private Field saleShopUserId;
    private Field saleShopSalesId;
    private Field saleShopNumber;
    private Field saleShopSubtotal;
    private Field saleShopDiscountPercent;
    private Field saleShopDiscountNominal;
    private Field saleShopTotal;
    private Field saleShopDate;
    private Field saleShopTimestamp;

    public SaleShop() {
        super();
        setTheClass(PosTransactionSaleShop.class);
        setPageDetail(SaleShopDetail.class);

        saleShopId = new Field();
        saleShopId.setName("saleShopId");
        saleShopId.setCaption("id");
        saleShopId.setListProperties("");
        saleShopId.setInputProperties("");
        getFields().add(saleShopId);

        saleShopUnitId = new Field();
        saleShopUnitId.setName("saleShopUnitId");
        saleShopUnitId.setCaption("unit id");
        saleShopUnitId.setListProperties("");
        saleShopUnitId.setInputProperties("");
        getFields().add(saleShopUnitId);

        saleShopUserId = new Field();
        saleShopUserId.setName("saleShopUserId");
        saleShopUserId.setCaption("user id");
        saleShopUserId.setListProperties("");
        saleShopUserId.setInputProperties("");
        getFields().add(saleShopUserId);
        
        saleShopSalesId = new Field();
        saleShopSalesId.setName("saleShopSalesId");
        saleShopSalesId.setCaption("sales");
        saleShopSalesId.setListProperties(" align=\"center\" width=\"15%\" nowrap");
        saleShopSalesId.setInputProperties(" size=\"30\" ");
        saleShopSalesId.setRequired(true);
        saleShopSalesId.getSelectorColumns().add(new String[]{"salesName", " Name", "align=\"left\" width=\"20%\" nowrap"});
        saleShopSalesId.getSelectorColumns().add(new String[]{"salesUnitId", " Unit", "align=\"left\" width=\"30%\""});
        saleShopSalesId.getSelectorColumns().add(new String[]{"salesAddress", " Address", "align=\"left\" width=\"50%\" nowrap"});
        getFields().add(saleShopSalesId);
        
        saleShopNumber = new Field();
        saleShopNumber.setName("saleShopNumber");
        saleShopNumber.setCaption("number");
        saleShopNumber.setListProperties(" align=\"center\" width=\"15%\" nowrap");
        saleShopNumber.setInputProperties(" size=\"20\" readonly");
        saleShopNumber.setRequired(true);
        getFields().add(saleShopNumber);

        saleShopSubtotal = new Field();
        saleShopSubtotal.setName("saleShopSubtotal");
        saleShopSubtotal.setCaption("subtotal");
        saleShopSubtotal.setListProperties(" align=\"right\" width=\"20%\" nowrap");
        saleShopSubtotal.setInputProperties(" size=\"8\"");
        saleShopSubtotal.setRequired(true);
        saleShopSubtotal.setFormater(MoneyFormatter.getInstance());
        getFields().add(saleShopSubtotal);

        saleShopDiscountPercent = new Field();
        saleShopDiscountPercent.setName("saleShopDiscountPercent");
        saleShopDiscountPercent.setCaption("discount percent");
        saleShopDiscountPercent.setListProperties(" align=\"right\" width=\"15%\" nowrap");
        saleShopDiscountPercent.setInputProperties(" size=\"8\"");
        getFields().add(saleShopDiscountPercent);

        saleShopDiscountNominal = new Field();
        saleShopDiscountNominal.setName("saleShopDiscountNominal");
        saleShopDiscountNominal.setCaption("discount nominal");
        saleShopDiscountNominal.setListProperties(" align=\"right\" width=\"20%\" nowrap");
        saleShopDiscountNominal.setInputProperties(" size=\"8\"");
        saleShopDiscountNominal.setFormater(MoneyFormatter.getInstance());
        getFields().add(saleShopDiscountNominal);

        saleShopTotal = new Field();
        saleShopTotal.setName("saleShopTotal");
        saleShopTotal.setCaption("total");
        saleShopTotal.setListProperties(" align=\"right\" width=\"20%\" nowrap");
        saleShopTotal.setInputProperties(" size=\"8\"");
        saleShopTotal.setRequired(true);
        saleShopTotal.setFormater(MoneyFormatter.getInstance());
        getFields().add(saleShopTotal);

        saleShopDate = new Field();
        saleShopDate.setName("saleShopDate");
        saleShopDate.setCaption("date");
        saleShopDate.setListProperties(" align=\"center\" width=\"10%\" nowrap");
        saleShopDate.setInputProperties(" size=\"8\" readonly");
        saleShopDate.setDefaultValue(Utility.getTimestamp());
        getFields().add(saleShopDate);

        saleShopTimestamp = new Field();
        saleShopTimestamp.setName("saleShopTimestamp");
        saleShopTimestamp.setCaption("timestamp");
        saleShopTimestamp.setListProperties(" align=\"center\" width=\"15%\" nowrap");
        saleShopTimestamp.setInputProperties(" size=\"8\" readonly");
        saleShopTimestamp.setDefaultValue(Utility.getTimestamp());
        getFields().add(saleShopTimestamp);

        getActions().add(Action.TRANS_ADD);
        getActions().add(Action.TRANS_VIEW);
        
        fillFields();

        getFieldsAdd().clear();
        getFieldsAdd().add(saleShopDate);
        getFieldsAdd().add(saleShopNumber);
        getFieldsAdd().add(saleShopSalesId);
        getFieldsAdd().add(saleShopDiscountPercent);
        getFieldsAdd().add(saleShopDiscountNominal);

        getFieldsEdit().clear();
        getFieldsEdit().add(saleShopNumber);
        getFieldsEdit().add(saleShopDate);
        getFieldsEdit().add(saleShopSalesId);
        getFieldsEdit().add(saleShopDiscountPercent);
        getFieldsEdit().add(saleShopDiscountNominal);

        getFieldsList().clear();
        getFieldsList().add(saleShopNumber);
        getFieldsList().add(saleShopDate);
        getFieldsList().add(saleShopSalesId);
        getFieldsList().add(saleShopSubtotal);
        getFieldsList().add(saleShopDiscountPercent);
        getFieldsList().add(saleShopDiscountNominal);
        getFieldsList().add(saleShopTotal);

        getFieldsView().clear();
        getFieldsView().add(saleShopNumber);
        getFieldsView().add(saleShopSubtotal);
        getFieldsView().add(saleShopSalesId);
        getFieldsView().add(saleShopDiscountPercent);
        getFieldsView().add(saleShopDiscountNominal);
        getFieldsView().add(saleShopTotal);
        getFieldsView().add(saleShopTimestamp);

        setController(new SaleController(this));
        setExportList(getClass().getResourceAsStream("SaleShopList.jasper"));
        setExport(getClass().getResourceAsStream("SaleShop.jasper"));
    }

    @Override
    public void afterInit(HttpServletRequest req, HttpServletResponse res) {
        saleShopTimestamp.setFormater(DateFormatter.getInstanceDate(this));
    }

    @Override
    public void loadDetail(List datas, String id) {
        try {
            EntityManager em = getEntityManager();
            List<PosTransactionSaleShopDetail> request = em.createQuery("SELECT t FROM PosTransactionSaleShopDetail t WHERE t.saleShopDetailSaleId.saleShopId='" + id + "'").setHint(Persistence.REFRESH_HINT, true).getResultList();
            datas.clear();
            for (PosTransactionSaleShopDetail saleShopDetail : request) {
                PosTransactionSaleShop saleShop = new PosTransactionSaleShop();
                saleShop.setSaleShopDiscountNominal(saleShopDetail.getSaleShopDetailDiscountNominal());
                saleShop.setSaleShopDiscountPercent(saleShopDetail.getSaleShopDetailDiscountPercent());
                datas.add(saleShop);
            }
        } catch (Exception e) {
            Logger.getInstance().log(e);
        }
    }

    @Override
    public void beforeAdd() {
        saleShopNumber.setDefaultValue(generate());
    }

    class SaleController extends Controller {

        public SaleController(Page page) {
            super(page);
            setOrder(saleShopTimestamp);
            setOrderType("DESC");
        }

        @Override
        public void beforeInsert(Object data, List list) {
            HttpSession session = getRequest().getSession();
            PosTransactionSaleShop saleShop = (PosTransactionSaleShop) data;
            saleShop.setSaleShopNumber(generate());
            saleShop.setSaleShopUserId(getCurrentUser());
            saleShop.setSaleShopUnitId(getCurrentUnit());
            saleShop.setSaleShopTimestamp(Utility.getTimestamp());
            
//            for (int i = list.size() - 1; i > 0; i--) {
//                PosTransactionSaleShopDetail d1 = (PosTransactionSaleShopDetail) list.get(i);
//                for (int j = 0; j < i; j++) {
//                    PosTransactionSaleShopDetail d2 = (PosTransactionSaleShopDetail) list.get(j);
//                    if (d2.getSaleShopDetailItemId().equals(d1.getSaleShopDetailItemId())) {
//                        d2.setSaleShopDetailQuantity(d2.getSaleShopDetailQuantity()+d1.getSaleShopDetailQuantity());
//                        list.remove(i);
//                        break;
//                    }
//                }
//            }

            BigDecimal subTotal = BigDecimal.ZERO;
            for (int i = 0; i < list.size(); i++) {
                PosTransactionSaleShopDetail saleShopDetail = (PosTransactionSaleShopDetail) list.get(i);
                subTotal = subTotal.add(saleShopDetail.getSaleShopDetailTotal());
            }
            BigDecimal total = subTotal;
            BigDecimal percent = BigDecimal.ZERO;
            try {
                percent = subTotal.multiply(saleShop.getSaleShopDiscountPercent().divide(new BigDecimal(100)));
            } catch (Exception e) {
                Logger.getInstance().log(e);
            }
            total = total.subtract(percent);
            try {
                total = total.subtract(saleShop.getSaleShopDiscountNominal());
            } catch (Exception e) {
                Logger.getInstance().log(e);
            }
            saleShop.setSaleShopSubtotal(subTotal);
            saleShop.setSaleShopTotal(total);
        }

        @Override
        public void afterInsert(Object data, List list) {
            EntityManager em = getEntityManager();
            PosMasterStatus statusGood = Status.getStatusGood(em);
            try {
                em.getTransaction().begin();
                PosTransactionSaleShop saleShop = (PosTransactionSaleShop) data;
                for (Object detail : list) {
                    PosTransactionSaleShopDetail saleShopDetail = (PosTransactionSaleShopDetail) detail;
                    PosMasterItemStock stock = Item.getStock(em, saleShopDetail.getSaleShopDetailItemId(), saleShop.getSaleShopUnitId(), statusGood, saleShopDetail.getSaleShopDetailItemId().getItemColorId(), saleShopDetail.getSaleShopDetailSizeId());
                    PosTransactionItemStock itemStock = new PosTransactionItemStock();
                    itemStock.setItemStockId(Sequence.next(itemStock));
                    itemStock.setItemStockItemId(saleShopDetail.getSaleShopDetailItemId());
                    itemStock.setItemStockSizeId(saleShopDetail.getSaleShopDetailSizeId());
                    itemStock.setItemStockColorId(saleShopDetail.getSaleShopDetailItemId().getItemColorId());
                    itemStock.setItemStockUnitId(saleShop.getSaleShopUnitId());
                    itemStock.setItemStockStatusId(statusGood);
                    itemStock.setItemStockType("6");
                    itemStock.setItemStockLast(stock.getItemStockValue());
                    itemStock.setItemStockValue(saleShopDetail.getSaleShopDetailQuantity());
                    itemStock.setItemStockCurrent(itemStock.getItemStockLast() - itemStock.getItemStockValue());
                    itemStock.setItemStockUserId(page.getCurrentUser());
                    itemStock.setItemStockTimestamp(Utility.getTimestamp());
                    em.persist(itemStock);
                    stock.setItemStockValue(itemStock.getItemStockCurrent());
                    if (saleShopDetail.getSaleShopDetailQuantity().compareTo(itemStock.getItemStockValue()) > 0) {
                        Utility.throwException(saleShopDetail.getSaleShopDetailItemId() + " " + Dictionary.getValue(page, "insufficient stock") + ", " +Dictionary.getValue(page, "current stock: ") + ": " + stock.getItemStockValue() + " " + Dictionary.getValue(page, "will be sent") + ": " + saleShopDetail.getSaleShopDetailQuantity());
                    }
                }
                em.getTransaction().commit();
            } catch (Exception e) {
                Logger.getInstance().log(e);
            }
        }
    }

    public String generate() {
        HttpSession session = getRequest().getSession();
        String unitCode = (getCurrentUnit()).getUnitCode();
        Calendar cal = Calendar.getInstance();
        String year = "" + cal.get(Calendar.YEAR);
        String month = Utility.intToRoman(cal.get(Calendar.MONTH) + 1);
        try {
            PosTransactionSaleShop saleShop = (PosTransactionSaleShop) getEntityManager().createQuery("SELECT t FROM PosTransactionSaleShop t WHERE t.saleShopNumber LIKE '%/" + unitCode + "/SAS/%/" + year + "' ORDER BY t.saleShopTimestamp DESC").setHint(Persistence.REFRESH_HINT, true).setFirstResult(0).setMaxResults(1).getSingleResult();
            return Utility.lpad(Integer.parseInt(saleShop.getSaleShopNumber().substring(0, 4)) + 1, 4, "0") + "/" + unitCode + "/SAS/" + month + "/" + year;
        } catch (Exception e) {
        }
        return "0001/" + unitCode + "/SAS/" + month + "/" + year;
    }

    @Override
    public void beforeExport() {
        getExportParams().put("title", Dictionary.getValue(this, "Sale Shop"));
    }

    @Override
    public void beforeExportMulti() {
        beforeExport();
    }
}
